package util

import (
	"math"
	"reflect"
	"strconv"
)

// 判断两个值是否相等
func EqualTo(value any, targetValue any) bool {
	if value == nil {
		return targetValue == nil
	}

	// 相同类型直接比较
	if vType := reflect.TypeOf(targetValue); vType != nil && vType == reflect.TypeOf(value) {
		return reflect.DeepEqual(value, targetValue)
	}

	// 使用类型断言处理常见数值类型
	switch v := targetValue.(type) {
	case int:
		return EqualToInt(value, v)
	case int8:
		return EqualToInt(value, int(v))
	case int16:
		return EqualToInt(value, int(v))
	case int32:
		return EqualToInt(value, int(v))
	case int64:
		return EqualToInt64(value, v)
	case uint:
		return EqualToUint(value, v)
	case uint8:
		return EqualToUint(value, uint(v))
	case uint16:
		return EqualToUint(value, uint(v))
	case uint32:
		return EqualToUint(value, uint(v))
	case uint64:
		return EqualToUint64(value, v)
	case float32:
		return EqualToFloat64(value, float64(v))
	case float64:
		return EqualToFloat64(value, v)
	case string:
		return EqualToString(value, v)
	default:
		return reflect.DeepEqual(value, targetValue)
	}
}

// EqualToInt 处理与int的比较
func EqualToInt(value any, targetValue int) bool {
	switch t := value.(type) {
	case int:
		return t == targetValue
	case int8:
		return int(t) == targetValue && targetValue >= math.MinInt8 && targetValue <= math.MaxInt8
	case int16:
		return int(t) == targetValue && targetValue >= math.MinInt16 && targetValue <= math.MaxInt16
	case int32:
		return int(t) == targetValue && targetValue >= math.MinInt32 && targetValue <= math.MaxInt32
	case int64:
		return int64(targetValue) == t && targetValue >= math.MinInt64/math.MaxInt && targetValue <= math.MaxInt64/math.MaxInt
	case uint:
		return uint(targetValue) == t && targetValue >= 0
	case uint8:
		return uint(targetValue) == uint(t) && targetValue >= 0 && targetValue <= 255
	case uint16:
		return uint(targetValue) == uint(t) && targetValue >= 0 && targetValue <= 65535
	case uint32:
		return uint64(targetValue) == uint64(t) && targetValue >= 0 && uint64(targetValue) <= math.MaxUint32
	case uint64:
		return uint64(targetValue) == t && targetValue >= 0
	case float32:
		return float64(targetValue) == float64(t)
	case float64:
		return float64(targetValue) == t
	case string:
		n, err := strconv.ParseInt(t, 10, 64)
		return err == nil && int64(targetValue) == n
	default:
		return false
	}
}

// EqualToInt64 处理与int64的比较
func EqualToInt64(value any, targetValue int64) bool {
	switch t := value.(type) {
	case int:
		return int64(t) == targetValue && t <= math.MaxInt64 && t >= math.MinInt64
	case int8:
		return int64(t) == targetValue && targetValue >= math.MinInt8 && targetValue <= math.MaxInt8
	case int16:
		return int64(t) == targetValue && targetValue >= math.MinInt16 && targetValue <= math.MaxInt16
	case int32:
		return int64(t) == targetValue && targetValue >= math.MinInt32 && targetValue <= math.MaxInt32
	case int64:
		return t == targetValue
	case uint:
		return uint64(targetValue) == uint64(t) && targetValue >= 0
	case uint8:
		return uint64(targetValue) == uint64(t) && targetValue >= 0 && targetValue <= 255
	case uint16:
		return uint64(targetValue) == uint64(t) && targetValue >= 0 && targetValue <= 65535
	case uint32:
		return uint64(targetValue) == uint64(t) && targetValue >= 0 && targetValue <= math.MaxUint32
	case uint64:
		return targetValue >= 0 && uint64(targetValue) == t
	case float32:
		return float64(targetValue) == float64(t)
	case float64:
		return float64(targetValue) == t
	case string:
		n, err := strconv.ParseInt(t, 10, 64)
		return err == nil && targetValue == n
	default:
		return false
	}
}

// EqualToUint 处理与uint的比较
func EqualToUint(value any, targetValue uint) bool {
	switch t := value.(type) {
	case int:
		return t >= 0 && uint(t) == targetValue
	case int8:
		return t >= 0 && uint(t) == targetValue
	case int16:
		return t >= 0 && uint(t) == targetValue
	case int32:
		return t >= 0 && uint(t) == targetValue
	case int64:
		return t >= 0 && uint64(t) == uint64(targetValue)
	case uint:
		return t == targetValue
	case uint8:
		return uint(t) == targetValue
	case uint16:
		return uint(t) == targetValue
	case uint32:
		return uint64(targetValue) == uint64(t) && targetValue <= math.MaxUint32
	case uint64:
		return uint64(targetValue) == t && targetValue <= math.MaxUint64
	case float32:
		return float64(targetValue) == float64(t) && t >= 0 && float64(targetValue) <= float64(math.MaxUint)
	case float64:
		return float64(targetValue) == t && t >= 0 && float64(targetValue) <= float64(math.MaxUint)
	case string:
		n, err := strconv.ParseUint(t, 10, 64)
		return err == nil && uint64(targetValue) == n
	default:
		return false
	}
}

// EqualToUint64 处理与uint64的比较
func EqualToUint64(value any, targetValue uint64) bool {
	switch t := value.(type) {
	case int:
		return t >= 0 && uint64(t) == targetValue
	case int8:
		return t >= 0 && uint64(t) == targetValue
	case int16:
		return t >= 0 && uint64(t) == targetValue
	case int32:
		return t >= 0 && uint64(t) == targetValue
	case int64:
		return t >= 0 && uint64(t) == targetValue
	case uint:
		return uint64(t) == targetValue
	case uint8:
		return uint64(t) == targetValue
	case uint16:
		return uint64(t) == targetValue
	case uint32:
		return uint64(t) == targetValue
	case uint64:
		return t == targetValue
	case float32:
		return float64(targetValue) == float64(t) && t >= 0 && float64(targetValue) <= float64(math.MaxUint64)
	case float64:
		return float64(targetValue) == t && t >= 0 && float64(targetValue) <= float64(math.MaxUint64)
	case string:
		n, err := strconv.ParseUint(t, 10, 64)
		return err == nil && targetValue == n
	default:
		return false
	}
}

// EqualToFloat64 处理与float64的比较
func EqualToFloat64(value any, targetValue float64) bool {
	// 考虑浮点数精度问题，使用容差比较
	epsilon := 1e-9
	switch t := value.(type) {
	case int:
		return float64(t) == targetValue
	case int8:
		return float64(t) == targetValue
	case int16:
		return float64(t) == targetValue
	case int32:
		return float64(t) == targetValue
	case int64:
		return float64(t) == targetValue
	case uint:
		return float64(t) == targetValue
	case uint8:
		return float64(t) == targetValue
	case uint16:
		return float64(t) == targetValue
	case uint32:
		return float64(t) == targetValue
	case uint64:
		return float64(t) == targetValue
	case float32:
		return math.Abs(float64(t)-targetValue) < epsilon
	case float64:
		return math.Abs(t-targetValue) < epsilon
	case string:
		n, err := strconv.ParseFloat(t, 64)
		return err == nil && math.Abs(n-targetValue) < epsilon
	default:
		return false
	}
}

// EqualToString 处理与string的比较
func EqualToString(value any, targetValue string) bool {
	switch t := value.(type) {
	case string:
		return t == targetValue
	case int:
		return strconv.Itoa(t) == targetValue
	case int8:
		return strconv.FormatInt(int64(t), 10) == targetValue
	case int16:
		return strconv.FormatInt(int64(t), 10) == targetValue
	case int32:
		return strconv.FormatInt(int64(t), 10) == targetValue
	case int64:
		return strconv.FormatInt(t, 10) == targetValue
	case uint:
		return strconv.FormatUint(uint64(t), 10) == targetValue
	case uint8:
		return strconv.FormatUint(uint64(t), 10) == targetValue
	case uint16:
		return strconv.FormatUint(uint64(t), 10) == targetValue
	case uint32:
		return strconv.FormatUint(uint64(t), 10) == targetValue
	case uint64:
		return strconv.FormatUint(t, 10) == targetValue
	case float32:
		return strconv.FormatFloat(float64(t), 'f', -1, 32) == targetValue
	case float64:
		return strconv.FormatFloat(t, 'f', -1, 64) == targetValue
	case bool:
		return strconv.FormatBool(t) == targetValue
	default:
		return false
	}
}
